package com.zzl.study.auth.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zzl.study.auth.security.authentication.client.GatewayOAuth2AuthorizedClient;
import com.zzl.study.auth.security.authentication.context.Authentication;
import com.zzl.study.auth.utils.JacksonUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @author: zhangzl
 * @date: 2024/6/6 20:00
 * @version: 1.0
 * @description: Redis 配置类
 */
@Configuration
public class RedisConfig {

    /**
     * 向Spring容器中注入一个存储认证信息存储的RedisTemplate
     *
     * @param factory redis连接工厂
     * @return 存储认证信息存储的RedisTemplate
     */
    @Bean
    public ReactiveRedisTemplate<String, Authentication> authenticationRedisTemplate(ReactiveRedisConnectionFactory factory) {
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        ObjectMapper objectMapper = JacksonUtils.getObjectMapper();
        Jackson2JsonRedisSerializer<Authentication> valueSerializer = new Jackson2JsonRedisSerializer<>(objectMapper, Authentication.class);
        RedisSerializationContext<String, Authentication> context = RedisSerializationContext.<String, Authentication>newSerializationContext()
                .key(stringSerializer)
                .value(valueSerializer)
                .hashKey(stringSerializer)
                .hashValue(valueSerializer)
                .build();
        return new ReactiveRedisTemplate<>(factory, context);
    }

    /**
     * 向Spring容器中注入一个存储OAuth2认证客户端的RedisTemplate
     *
     * @param factory redis连接工厂
     * @return 存储OAuth2认证客户端的RedisTemplate
     */
    @Bean
    public ReactiveRedisTemplate<String, GatewayOAuth2AuthorizedClient> oauth2AuthorizedClientRedisTemplate(ReactiveRedisConnectionFactory factory) {
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        ObjectMapper objectMapper = JacksonUtils.getObjectMapper();
        Jackson2JsonRedisSerializer<GatewayOAuth2AuthorizedClient> valueSerializer = new Jackson2JsonRedisSerializer<>(objectMapper, GatewayOAuth2AuthorizedClient.class);
        RedisSerializationContext<String, GatewayOAuth2AuthorizedClient> context = RedisSerializationContext.<String, GatewayOAuth2AuthorizedClient>newSerializationContext()
                .key(stringSerializer)
                .value(valueSerializer)
                .hashKey(stringSerializer)
                .hashValue(valueSerializer)
                .build();
        return new ReactiveRedisTemplate<>(factory, context);
    }

}
